博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Spring 5 官方文档》18. Web MVC 框架(七)
阅读量:5837 次
发布时间:2019-06-18

本文共 8641 字,大约阅读时间需要 28 分钟。

18.5.4 ContentNegotiatingViewResolver

ContentNegotiatingViewResolver不会解析视图本身,而是委托给其他视图解析器,选择类似于客户端请求的表示的视图。客户端可以从服务器请求表示方式存在两种策略:

  • 通常通过在URI中使用不同的文件扩展名为每个资源使用不同的URI。例如,URI 请求用户fred的PDF表示,并请求XML表示。
  • 使用相同的URI来为客户端定位资源,但设置AcceptHTTP请求标头以列出它理解的。例如,一个HTTP请求, 其中一个Accept头设置为application/pdf 请求用户fred的PDF表示,同时 使用Accept头设置来text/xml请求XML表示。这个策略被称为 。
[注意]
Accept标题的一个问题是,不可能在HTML中的Web浏览器中设置它。例如,在Firefox中,它被修改为:

接受:text / html,application / xhtml + xml,application / xml; q = 0.9,* / *; q = 0.8

因此,在开发基于浏览器的Web应用程序时,通常会看到每个表示使用不同的URI。

为了支持资源的多个表示,Spring提供了 ContentNegotiatingViewResolver根据AcceptHTTP请求的文件扩展名或头部来解析视图。ContentNegotiatingViewResolver不执行视图分辨率本身,而是委托给您通过bean属性指定的视图解析器的列表ViewResolvers

ContentNegotiatingViewResolver选择一个合适的View通过比较与所述媒体类型(也被称为媒体请求类型(一个或多个),以处理该请求 Content-Type由支持)的View与每个其相关联ViewResolversView具有兼容性的列表中的第一个将表示Content-Type返回给客户端。如果链条不能提供兼容的视图,则会查看ViewResolver通过DefaultViews属性指定的视图列表。后一个选项适用于Views可以呈现当前资源的适当表示的单例,而不管逻辑视图名称如何。的Accept 报头可以包括通配符,例如text/*,在这种情况下View,其内容类型是text/xml为相容的匹配。

要支持基于文件扩展名的视图的自定义解析,请使用 ContentNegotiationManager:请参见。

以下是一个示例配置ContentNegotiatingViewResolver

web.servlet.view.json.MappingJackson2JsonView“ />
web.servlet.view.json.MappingJackson2JsonView“ />
 

InternalResourceViewResolver手柄视图名称和JSP页面的翻译,而BeanNameViewResolver返回基于bean的名称的视图。(有关Spring如何查找和实例化视图的更多详细信息,请参阅“ 解析视图”。)在此示例中,该content bean是继承的类,该类AbstractAtomFeedView返回Atom RSS提要。有关创建Atom Feed表示的更多信息,请参阅Atom视图。

在上述配置中,如果使用扩展名进行请求.html,视图解析器将查找与text/html媒体类型匹配的视图。在 InternalResourceViewResolver提供了用于匹配视图text/html。如果请求是使用文件扩展名.atom,视图解析器将查找与application/atom+xml媒体类型相匹配的视图。该视图由该 BeanNameViewResolver映射提供给SampleContentAtomView如果返回的视图名称是content。如果使用文件扩展名进行请求.json,则无论视图名称如何, MappingJackson2JsonView将从DefaultViews列表中选择实例。或者,客户端请求可以在没有文件扩展名的情况下进行,但是将Accept标题设置为首选媒体类型,并且将发生对视图请求的相同解析。

[注意]
如果“ContentNegotiatingViewResolver”的ViewResolver列表未被明确配置,它会自动使用应用程序上下文中定义的任何ViewResolvers。

相应的控制器代码返回表单的URI 应用Accept程序/ atom + xml 的头部的Atom RSS提要 如下所示。

@Controller public  class ContentController {	private List 
contentList = new ArrayList
(); @GetMapping(“/ content”) public ModelAndView getContent(){ ModelAndView mav = new ModelAndView(); mav.setViewName(“content”); mav.addObject(“sampleContentList”,contentList); 返回 mav }}

18.6使用flash属性

Flash属性为一个请求存储旨在用于另一个的属性提供了一种方法。这是重定向时最常用的 – 例如 Post / Redirect / Get模式。闪存属性在重定向(通常在会话中)之前临时保存,以便在重定向后立即对请求提供可用的请求。

Spring MVC有两个主要的抽象支持Flash属性。FlashMap用于保存Flash属性,FlashMapManager用于存储,检索和管理 FlashMap实例。

Flash属性支持始终是“开”的,不需要明确启用,尽管如果不使用它,它不会导致HTTP会话创建。在每个请求上都有一个“输入” FlashMap,它具有从先前的请求传递的属性(如果有的话)和FlashMap带有属性的“输出” ,以保存后续请求。这两个FlashMap实例可以通过静态方法在Spring MVC中从任何地方访问RequestContextUtils

注释控制器通常不需要FlashMap直接使用。相反, @RequestMapping方法可以接受类型的参数,RedirectAttributes并使用它来为重定向方案添加闪存属性。添加的Flash属性将 RedirectAttributes自动传播到“输出”FlashMap。类似地,在重定向之后,来自“输入” FlashMap的属性将自动添加到 Model为目标URL提供服务的控制器中。

18.7构建URI

Spring MVC提供了一种用于使用UriComponentsBuilder和构建和编码URI的机制 UriComponents

例如,您可以扩展和编码URI模板字符串:

UriComponents uriComponents = UriComponentsBuilder.fromUriString(		 “http://example.com/hotels/{hotel}/bookings/{booking}”).build();URI uri = uriComponents.expand(“42”,“21”).encode()。toUri();

请注意,这UriComponents是不可变的expand()encode()如果需要,并且操作返回新的实例。

您还可以使用各个URI组件进行扩展和编码:

UriComponents uriComponents = UriComponentsBuilder.newInstance()		.scheme(“http”). host(“example.com”).path(“/酒店/ {酒店} /预订/ {预订}”).build()		.expand(“42”,“21”)		.encode();

在Servlet环境中,ServletUriComponentsBuilder子类提供静态工厂方法从Servlet请求中复制可用的URL信息:

HttpServletRequest request = ...//重新使用host,scheme,port,path和query string //替换“accountId”查询参数ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromRequest(request)		.replaceQueryParam(“accountId”,“{id}”).build()		.expand(“123”)		.encode();

或者,您可以选择复制可用信息的子集,直到并包括上下文路径:

//重新使用主机,端口和上下文路径//将“/ accounts”附加到路径ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromContextPath(request)		.path(“/ accounts”).build()

或者在DispatcherServlet按名称(例如/main/*)映射的情况下,还可以包含servlet映射的文字部分:

//重新使用主机,端口,上下文路径//将servlet映射的文字部分附加到路径//将“/ accounts”附加到路径ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromServletMapping(request)		.path(“/ accounts”).build()

18.7.1构建控制器和方法的URI

Spring MVC还提供了一种构建控制器方法链接的机制。例如,给出:

@Controller @RequestMapping(“/ hotels / {hotel}”) public  class BookingController {	@GetMapping(“/ bookings / {booking}”)	 public String getBooking( @PathVariable Long booking){	// ...       }}

您可以通过名称参考方法来准备链接:

UriComponents uriComponents = MvcUriComponentsBuilder	.fromMethodName(BookingController 类,“getBooking” ,21).buildAndExpand(42);URI uri = uriComponents.encode()。toUri();

在上面的例子中,我们提供了实际的方法参数值,在这种情况下是长值21,用作路径变量并插入到URL中。此外,我们提供了值42,以填充任何剩余的URI变量,例如从类型级请求映射继承的“hotel”变量。如果该方法有更多的参数,您可以为URL不需要的参数提供null。一般而言@PathVariable@RequestParam参数与构造URL相关。

还有其他的使用方法MvcUriComponentsBuilder。例如,您可以使用类似于通过代理模拟测试的技术,以避免通过名称引用控制器方法(示例假定静态导入MvcUriComponentsBuilder.on):

UriComponents uriComponents = MvcUriComponentsBuilder	.fromMethodCall(上(BookingController。类).getBooking(21))buildAndExpand(42);URI uri = uriComponents.encode()。toUri();

上面的例子使用静态方法MvcUriComponentsBuilder。在内部,他们依靠ServletUriComponentsBuilder从当前请求的方案,主机,端口,上下文路径和servlet路径准备基本URL。这在大多数情况下运行良好,但有时可能不足。例如,您可能不在请求的上下文中(例如,准备链接的批处理),或者您可能需要插入路径前缀(例如,从请求路径中删除并需要重新插入到链接中的区域设置前缀)。

对于这种情况,您可以使用接受a UriComponentsBuilder使用基本URL 的静态“fromXxx”重载方法 。或者您可以MvcUriComponentsBuilder 使用基本URL 创建一个实例,然后使用基于实例的“withXxx”方法。例如:

UriComponentsBuilder base = ServletUriComponentsBuilder.fromCurrentContextPath()。path(“/ en”);MvcUriComponentsBuilder builder = MvcUriComponentsBuilder.relativeTo(base);builder.withMethodCall(上(BookingController。类).getBooking(21))buildAndExpand(42);URI uri = uriComponents.encode()。toUri();

18.7.2构建来自视图的控制器和方法的URI

您还可以从JSP,Thymeleaf,FreeMarker等视图中构建带注释控制器的链接。这可以使用fromMappingName方法,MvcUriComponentsBuilder 其中指的是按名称映射。

每个都会@RequestMapping根据类的大写字母和完整的方法名称分配一个默认名称。例如,getFooFooController 中的方法被分配名称“FC#getFoo”。该策略可以通过创建一个实例HandlerMethodMappingNamingStrategy并将其插入到您中 来进行替换或定制RequestMappingHandlerMapping。默认策略实现也会查看name属性@RequestMapping,如果存在,则使用该属性。这意味着如果分配的默认映射名称与另一个冲突(例如重载方法),则可以在该目录上明确指定一个名称@RequestMapping

[注意]
分配的请求映射名称在启动时记录在TRACE级别。

Spring JSP标签库提供了一个名为mvcUrl该函数的函数,可用于根据此机制准备到控制器方法的链接。

例如:

@RequestMapping(“/ people / {id} / addresses”) public  class PersonAddressController {    @RequestMapping(“/ {country}”)     public HttpEntity getAddress( @PathVariable String country){...}}

您可以从JSP准备一个链接,如下所示:

%@ taglib uri =“http://www.springframework.org/tags”prefix =“s”%>...获取地址

上述示例依赖于mvcUrl在Spring标签库(即META-INF / spring.tld)中声明的JSP函数。对于更高级的案例(例如上一节所述的自定义基本URL),可以轻松地定义自己的函数或使用自定义标记文件,以便使用MvcUriComponentsBuilder具有自定义基本URL 的特定实例。

18.8使用区域设置

Spring的大部分架构支持国际化,就像Spring Web MVC框架一样。DispatcherServlet使您能够使用客户端的语言环境自动解析邮件。这是用LocaleResolver对象完成的。

当一个请求进来时,DispatcherServlet寻找一个区域设置解析器,如果它找到一个它试图使用它来设置区域设置。使用该RequestContext.getLocale() 方法,您可以随时检索由语言环境解析器解析的区域设置。

除了自动区域设置解析之外,您还可以将拦截器附加到处理程序映射(参见以获取有关处理程序映射拦截器的更多信息),以在特定情况下更改区域设置,例如,基于请求中的参数。

org.springframework.web.servlet.i18n程序包中定义了语言环境解析器和拦截器, 并以正常方式在应用程序上下文中配置。以下是Spring中包含的区域解析器的选择。

18.8.1获取时区信息

除了获取客户的区域设置之外,了解他们的时区通常也是有用的。该LocaleContextResolver界面提供了一个扩展LocaleResolver,允许解析器提供更丰富LocaleContext,可能包括时区信息。

如果可用,TimeZone可以使用该RequestContext.getTimeZone()方法获得 用户。时区信息将自动被Date / Time ConverterFormatterSpring注册的对象使用ConversionService

18.8.2 AcceptHeaderLocaleResolver

该语言环境解析器检查accept-language客户端发送的请求中的标题(例如,Web浏览器)。通常此标题字段包含客户端操作系统的区域设置。请注意,此解析器不支持时区信息。

18.8.3 CookieLocaleResolver

这个本地化解析器检查一个Cookie可能的客户端中,看是否有 LocaleTimeZone指定。如果是这样,它使用指定的细节。使用此语言环境解析器的属性,您可以指定cookie的名称以及最大的年龄。在下面找到一个定义a的例子CookieLocaleResolver

<! - 以秒为单位。如果设置为-1,则cookie不会持久化(在浏览器关闭时删除) - >

表18.4。CookieLocaleResolver属性

属性 默认 描述
cookieName classname + LOCALE cookie的名称
名cookieMaxAge Servlet容器默认 Cookie在客户端上保持持续的最长时间。如果指定了-1,则cookie不会被持久化; 只有客户端关闭浏览器才可用。
cookiePath / 将Cookie的可见性限制在您网站的某个部分。指定cookiePath时,cookie将只对该路径及其下方的路径可见。

18.8.4 SessionLocaleResolver

SessionLocaleResolver可以检索LocaleTimeZone从可能与用户的请求相关的会话。相反 CookieLocaleResolver,该策略将本地选择的区域设置存储在Servlet容器中HttpSession。因此,这些设置对于每个会话都是临时的,因此在每个会话终止时丢失。

请注意,与Spring Session项目之类的外部会话管理机制没有直接关系。这SessionLocaleResolver将简单地根据HttpSession当前值来评估和修改相应的属性HttpServletRequest

转载自

你可能感兴趣的文章
zabbix2.0安装与配置
查看>>
安装 apscheduler
查看>>
AndroidStudio——Unable to create Debug Bridge
查看>>
金庸笔下的爱情故事
查看>>
Cookie跨域操作
查看>>
SpringMVC与Activiti网页流程设计器整合
查看>>
“微信封杀”互联网公司躲不过的“坎儿”
查看>>
电脑如何批量压缩图片
查看>>
Python 语法速览与实战清单
查看>>
如何修改PDF文件内容,怎么编辑修改PDF背景
查看>>
iOS中的预编译指令的初步探究
查看>>
APP怎么制作
查看>>
Cocos2d入门--1--初涉相关属性或代码
查看>>
100G AOC有源光缆和100G高速线缆有什么区别?
查看>>
Device eth0 does not seem to be present, delaying initialization
查看>>
python包安装及安装包制作
查看>>
ubuntu 下载离线安装包及其依赖
查看>>
Data Guard保护模式解析及演示
查看>>
YUM升级CentOS系统中PHP和MySQL
查看>>
乾颐堂HCIE面试真题系列7
查看>>